<?php

namespace App\Http\Controllers\Api;

use App\Models\UserAddress;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Services\Api;
use App\Models\Cart;
use App\Models\ProductSku;
use App\Http\Resources\OrderProductSku;
use App\Http\Resources\UserAddress as UserAddressResource;
use App\Models\Coupon;
use App\Models\CustomerCoupon;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use App\Models\Order;
use App\Http\Resources\Orders;
use Illuminate\Support\Facades\DB;

class OrderController extends Controller
{
    /**
     * 订单列表
     */
    public function index(Request $request)
    {
        $data = $request->all([
            'page', 'limit',
            'status',
        ]);

        $orders = Order::where('customer_id', Auth::id())
            ->status($data['status'])
            ->latest('id')
            ->paginate($data['limit'] ?? 10);

        return Api::success(Orders::collection($orders));
    }

    /**
     * 订单详情
     */
    public function show(Request $request)
    {
        $orderId = $request->post('id');

        $order = Order::query()->find($orderId);

        if (!$order) {
            return Api::failure(404, '订单不存在！');
        }

        return Api::success($order->display());
    }

    /**
     * 生成订单
     */
    public function store(Request $request)
    {
        $data = $request->all([
            'ids', # 商品SKU_ID
            'invoice', # 发票信息
            'coupon', # 优惠券ID
            'remark', # 订单备注
            'address', # 收货地址ID
            'invoice', # 发票信息
            'payment', # 支付方式
            'postage', # 运费
        ]);

        $ids = json_decode($data['ids'], true);

        if (!$ids) {
            return Api::msg('api.order.product_not_found');
        }

        $products = $this->getProductByIds($ids);

        if ($products->isEmpty()) {
            return Api::msg('api.order.product_not_found');
        }

        $address = UserAddress::find($data['address']);

        if (!$address) {
            return Api::msg('api.order.address_not_found');
        }

        $order = Order::hasNewOrder([
            'customer_id' => Auth::id(),
            'address' => $address,
            'remark' => $data["remark"],
            'payment_method' => $data["payment"],
            'extra' => [
                'invoice' => json_decode($data["invoice"], true) ?: null,
                'postage' => price($data['postage']),
                'coupon' => $data['coupon']
            ],
            'total_account' => Order::price($products->pluck('price', 'id')),
            'total_amount' => array_sum($products->pluck('number')->toArray()),
            'cancel_at' => now()->addMinutes(30)->timestamp,
        ], $products);

        if (is_string($order)) {
            return Api::failure(500, $order);
        } else {
            return Api::msg('api.order.success', Orders::make($order));
        }
    }

    /**
     * 订单预览页面
     */
    public function prepare(Request $request)
    {
        $data = $request->all(['ids']);

        $ids = json_decode($data['ids'], true);

        if (!$ids) {
            return Api::msg('api.order.product_not_found');
        }

        $products = $this->getProductByIds($ids);

        if ($products->isEmpty()) {
            return Api::msg('api.order.product_not_found');
        }

        $coupons = $this->getCouponByProducts($products);

        $order = [
            'products' => OrderProductSku::collection($products),
            'addresses' => UserAddressResource::collection(Auth::user()->getAddresses()),
            'coupons' => $coupons,
            'payment_method' => Order::$payment,
            'postage' => price(0),
            'total_account' => Order::price($products->pluck('price', 'id')),
            // 'invoice' => Invoice::collection(Auth::user()->invoices), // 发票信息, 暂不需要
        ];

        return Api::msg('api.order.success', $order);
    }

    protected function getProductByIds($ids)
    {
        $carts = Cart::query()->whereIn('id', $ids)->get()->pluck('number', 'sku_id')->toArray();

        $skus = ProductSku::query()->with('product')->whereIn("id", array_keys($carts))->get();

        $skus->map(function (&$sku) use ($carts) {
            $sku->setAttribute('price', price($carts[$sku->id] * $sku->price["current"]));
            $sku->setAttribute('number', $carts[$sku->id]);
        });

        return $skus;
    }

    protected function getCouponByProducts($products)
    {
        /** @var Collection $coupons */
        $coupons = CustomerCoupon::canUse(Auth::user())->get();

        return $coupons->map(function ($coupon) use ($products) {
            $tmp = Coupon::format($coupon->coupons);
            $product = $products->map(function ($sku) use ($coupon) {
                if ($coupon->canUseOnProduct($sku->product)) {
                    return $sku->product_id;
                }
            });
            $tmp["product"] = array_filter($product->toArray());
            return $tmp;
        });
    }

    /**
     * 取消订单
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function cancel(Request $request)
    {
        $orderId = $request->post('id');
        $reason = $request->post('reason');

        /** @var Order $order */
        $order = Order::query()->find($orderId);

        if (!$order) {
            return Api::failure(404, '订单不存在');
        }

        if (!$reason) {
            return Api::failure(410, '取消原因不能为空');
        }

        DB::beginTransaction();
        try {
            if ($order->getHint()->toArray() === $order->getHint()->cancel((string)$reason)->toArray()) {
                return Api::failure(403, '当前订单不可取消！');
            }

            DB::commit();
        } catch (Exception $exception) {
            DB::rollBack();
            return Api::failure(500, '订单取消失败!');
        }

        return Api::success();
    }

    /**
     * 删除订单
     *
     * @param Request $request
     * @return JsonResponse
     * @throws Exception
     */
    public function delete(Request $request)
    {
        $orderId = $request->post('id');

        /** @var Order $order */
        $order = Order::query()->find($orderId);

        if (!$order) {
            return Api::failure(404, '订单不存在！');
        }

        // 已完成的订单才允许删除
        if ($order->getHint()->isFinish()) {
            $order->delete();
            return Api::success();
        }

        return Api::failure(403, '该订单不允许删除！');
    }

    /**
     * 确认收货
     *
     * @param Request $request
     * @return JsonResponse
     */
    public function receive(Request $request)
    {
        $orderId = $request->post('id');

        /** @var Order $order */
        $order = Order::query()->find($orderId);

        if (!$order) {
            return Api::failure(404, '订单不存在');
        }

        if ($order->getHint()->toArray() === $order->getHint()->receive()->toArray()) {
            return Api::failure(403, '该订单不允许收货！');
        }

        return Api::success();
    }
}
